import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import nl.jaapniek.db.DBManager;
import nl.jaapniek.exception.RdbmsException;
import nl.jaapniek.model.Criteria;
import nl.jaapniek.model.Database;
import nl.jaapniek.model.ForeignKey;
import nl.jaapniek.model.Groep;
import nl.jaapniek.model.Tabel;
import nl.jaapniek.model.Veld;

import org.hsqldb.Server;

public class Main {

	private static Server hsqlServer = null;
	private static Rdbms r = new Rdbms();

	public static void startHSQLServer() {
		// 'Server' is a class of HSQLDB representing
		// the database server

		hsqlServer = new Server();

		// HSQLDB prints out a lot of informations when
		// starting and closing, which we don't need now.
		// Normally you should point the setLogWriter
		// to some Writer object that could store the logs.
		hsqlServer.setLogWriter(null);
		hsqlServer.setSilent(true);

		// The actual database will be named 'xdb' and its
		// settings and data will be stored in files
		// testdb.properties and testdb.script
		hsqlServer.setDatabaseName(0, DBManager.DATABASE_NAAM);
		hsqlServer.setDatabasePath(0, "file:" + DBManager.DATABASE_NAAM);

		// Start the database!
		hsqlServer.start();
	}

	public static void stopHSQLServer() {
		// Closing the server
		if (hsqlServer != null) {
			hsqlServer.stop();
		}
	}

	public static void main(String[] args) {
		startHSQLServer();
		
		

//		createDatabase();
		init();
//		testFietsDb();
//		// Geen integriteits fouten
		testInsertInto();
//		// Proberen tabel te droppen die nog fk's heeft
		testDropTabel();
//		// rijen verwijderen die nog fk's hebben
		testDeleteMetFK();
//		// rijen succesvol verwijderen
		testDelete();
//		// dubbele insert
		testInsertDubbel();
		r.printDb();
		r.saveDatabases();
		testDubbeleDB();
		testDropDBNietBestaand();
		testUseDBNietBestaand();
		testTabel();
		testInsert();
		stopHSQLServer();

	}

	private static void init() {
		try {

			DBManager dbm = new DBManager();
			Connection con = dbm.openConnection();
			ResultSet rs1 = con.prepareStatement("SELECT * FROM database_impl")
					.executeQuery();
			while (rs1.next()) {
				r.createDatabase(rs1.getString(1));
				Database database = r.useDatabase(rs1.getString(1));
				System.out.println("Database "+ database.getNaam() + " wordt omgezet naar in-core");
				ResultSet rs2 = con.prepareStatement(
						"SELECT * FROM tabel WHERE database_naam='"
								+ database.getNaam() + "'").executeQuery();
				ArrayList<Groep> groepen = new ArrayList<Groep>();
				while (rs2.next()) {
					ArrayList<Veld> velden = new ArrayList<Veld>();
					ArrayList<ForeignKey> fKeys = new ArrayList<ForeignKey>();
					ArrayList<Veld> veldenVanTabel = new ArrayList<Veld>();
					ArrayList<Groep> groepenVanTabel = new ArrayList<Groep>();
					ArrayList<Groep> alternatives = new ArrayList<Groep>();
					ResultSet rs3 = con.prepareStatement(
							"SELECT * FROM veld WHERE database_naam='"
									+ database.getNaam() + "'").executeQuery();
					while (rs3.next()) {
						Veld veld = new Veld(rs3.getString(1),
								rs3.getString(4), rs3.getBoolean(5));
						veld.setTabelNaam(rs3.getString("tabel_naam"));
						if(rs3.getString("tabel_naam").equals(rs2.getString(1))){
							veldenVanTabel.add(veld);
						}
						velden.add(veld);
					}
					ResultSet rs4 = con.prepareStatement(
							"SELECT * FROM groep WHERE database_naam='"
									+ database.getNaam() + "'").executeQuery();
					while (rs4.next()) {
						Groep groep = new Groep(database, rs4.getBoolean(4),
								rs4.getBoolean(5));
						groep.setTabelNaam(rs4.getString(2));
						groep.setId(rs4.getInt(1));
						for (Veld veld : velden) {
							ResultSet rs5 = con.prepareStatement(
									"SELECT * FROM groep_attr WHERE groep_id='"
											+ groep.getId()
											+ "' AND veld_naam='"
											+ veld.getNaam() + "'")
									.executeQuery();
							while (rs5.next()) {
								if(veld.getTabelNaam().equals(groep.getTabelNaam())){
									groep.addGroepAttr(veld);
								}
							}
						}
						if (rs4.getString(2).equals(rs2.getString(1))) {
							if (!groep.isAlternative()) {
								groepenVanTabel.add(groep);
							} else {
								alternatives.add(groep);
							}
						}
						boolean add = true;
						for(Groep groep1 : groepen)
						{
							if(groep.getId() == groep1.getId()){
								add = false;
							}
						}
						if(add){
							groepen.add(groep);
						}
					}
					for (Groep groep : groepenVanTabel) {
						ResultSet rs6 = con.prepareStatement(
								"SELECT * FROM foreign_key WHERE from_groep='"
										+ groep.getId() + "'").executeQuery();
						while (rs6.next()) {
							int groepToId = rs6.getInt(2);
							ForeignKey fKey = new ForeignKey();
							fKey.setFromGroep(groep);
							for (Groep toGroep : groepen) {
								if (toGroep.getId() == groepToId) {
									fKey.setToGroep(toGroep);
								}
							}
							fKeys.add(fKey);
						}
					}
					Tabel tabel = r.createTable(rs2.getString(1), veldenVanTabel,
							groepenVanTabel, fKeys);
					for (Groep groep : alternatives) {
						r.addAlternativeKey(tabel, groep);
					}
				}

				r.fixFKs();
			}
			r.setNieuweDatabases(new ArrayList<Database>());

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private static void testFietsDb() {
		try {
			r.createDatabase("FietsDb");
			Database database = r.useDatabase("FietsDb");
			List<Veld> trackVelden = new ArrayList<Veld>();
			trackVelden.add(new Veld("Nummer", "int", true));
			trackVelden.add(new Veld("Naam", "string", true));
			trackVelden.add(new Veld("Rel-date", "date", true));

			List<Veld> knpTrackvelden = new ArrayList<Veld>();
			knpTrackvelden.add(new Veld("Track", "int", true));
			knpTrackvelden.add(new Veld("Long", "real", true));
			knpTrackvelden.add(new Veld("Lat", "real", true));
			knpTrackvelden.add(new Veld("Vlgnr", "int", true));

			List<Veld> knooppuntVelden = new ArrayList<Veld>();
			knooppuntVelden.add(new Veld("Lat", "real", true));
			knooppuntVelden.add(new Veld("Long", "real", true));
			knooppuntVelden.add(new Veld("Nummer", "int", true));
			knooppuntVelden.add(new Veld("Type", "string", false));

			List<Groep> trackGroepen = new ArrayList<Groep>();
			Groep groep1 = new Groep(database, true, false);
			groep1.addGroepAttr(trackVelden.get(0));
			groep1.setTabelNaam("TRACK");
			trackGroepen.add(groep1);

			List<Groep> knpTrackGroepen = new ArrayList<Groep>();
			Groep groep2 = new Groep(database, true, false);
			groep2.addGroepAttr(knpTrackvelden.get(0));
			groep2.addGroepAttr(knpTrackvelden.get(1));
			groep2.addGroepAttr(knpTrackvelden.get(2));
			groep2.setTabelNaam("KNPTRACK");

			Groep groep3 = new Groep(database, false, false);
			groep3.addGroepAttr(knpTrackvelden.get(0));
			groep3.setTabelNaam("KNPTRACK");

			Groep groep4 = new Groep(database, false, false);
			groep4.addGroepAttr(knpTrackvelden.get(1));
			groep4.addGroepAttr(knpTrackvelden.get(2));
			groep4.setTabelNaam("KNPTRACK");

			knpTrackGroepen.add(groep2);
			knpTrackGroepen.add(groep3);
			knpTrackGroepen.add(groep4);

			List<Groep> knooppuntGroepen = new ArrayList<Groep>();
			Groep groep5 = new Groep(database, true, false);
			groep5.addGroepAttr(knooppuntVelden.get(0));
			groep5.addGroepAttr(knooppuntVelden.get(1));
			knooppuntGroepen.add(groep5);
			groep5.setTabelNaam("KNOOPPUNT");

			List<ForeignKey> knpTrackFkeys = new ArrayList<ForeignKey>();
			knpTrackFkeys.add(new ForeignKey(groep3, groep1));
			knpTrackFkeys.add(new ForeignKey(groep4, groep5));

			Groep groep6 = new Groep(database, false, true);
			groep6.addGroepAttr(trackVelden.get(1));
			groep6.addGroepAttr(trackVelden.get(2));
			groep6.setTabelNaam("TRACK");
			
			Tabel track = r.createTable("TRACK", trackVelden, trackGroepen,
					null);
			r.addAlternativeKey(track, groep6);
			Tabel knooppunt = r.createTable("KNOOPPUNT", knooppuntVelden,
					knooppuntGroepen, null);
			Tabel knptrack = r.createTable("KNPTRACK", knpTrackvelden,
					knpTrackGroepen, knpTrackFkeys);
		} catch (RdbmsException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	private static void testInsertInto() {
		try {
			r.useDatabase("FietsDb");
			List<String> trackvelden = new ArrayList<String>();
			trackvelden.add("Nummer");
			trackvelden.add("Naam");
			trackvelden.add("Rel-date");
			List<Object> trackwaardes = new ArrayList<Object>();
			trackwaardes.add("1");
			trackwaardes.add("test");
			trackwaardes.add("27-05-2013");
			List<String> trackvelden1 = new ArrayList<String>();
			trackvelden1.add("Nummer");
			trackvelden1.add("Naam");
			trackvelden1.add("Rel-date");
			List<Object> trackwaardes1 = new ArrayList<Object>();
			trackwaardes1.add("2");
			trackwaardes1.add("test");
			trackwaardes1.add("21-05-2013");
			List<String> trackvelden2 = new ArrayList<String>();
			trackvelden2.add("Nummer");
			trackvelden2.add("Naam");
			trackvelden2.add("Rel-date");
			List<Object> trackwaardes2 = new ArrayList<Object>();
			trackwaardes2.add("3");
			trackwaardes2.add("testje");
			trackwaardes2.add("27-05-2013");

			List<String> knpTrackvelden = new ArrayList<String>();
			knpTrackvelden.add("Track");
			knpTrackvelden.add("Long");
			knpTrackvelden.add("Lat");
			knpTrackvelden.add("Vlgnr");
			List<Object> knpTrackwaardes = new ArrayList<Object>();
			knpTrackwaardes.add("1");
			knpTrackwaardes.add("34");
			knpTrackwaardes.add("2345");
			knpTrackwaardes.add("2");

			List<String> knooppuntVelden = new ArrayList<String>();
			knooppuntVelden.add("Lat");
			knooppuntVelden.add("Long");
			knooppuntVelden.add("Nummer");
			List<Object> knooppuntWaardes = new ArrayList<Object>();
			knooppuntWaardes.add("2345");
			knooppuntWaardes.add("34");
			knooppuntWaardes.add("1");
			
			r.insert("TRACK", trackvelden, trackwaardes);
			r.insert("TRACK", trackvelden1, trackwaardes1);
			r.insert("TRACK", trackvelden2, trackwaardes2);
			r.insert("KNOOPPUNT", knooppuntVelden, knooppuntWaardes);
			r.insert("KNPTRACK", knpTrackvelden, knpTrackwaardes);

			Map<Veld, ArrayList<Object>> resultset = r.select("TRACK",
					new Criteria("Nummer", ">", "1"));
			System.out.println(resultset);
		} catch (RdbmsException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	private static void testDropTabel() {
		try {
			r.useDatabase("FietsDb");
			r.dropTable("TRACK");
		} catch (RdbmsException e) {
			e.printStackTrace();
		}
	}

	private static void testDeleteMetFK() {
		try {
			r.useDatabase("FietsDb");
			r.delete("TRACK", null);
		} catch (RdbmsException e) {
			e.printStackTrace();
		}
	}
	
	private static void testDubbeleDB() {
		try {
			r.createDatabase("FietsDb");
		} catch (RdbmsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private static void testDropDBNietBestaand() {
		try {
			r.dropDatabase("Dezebestaatniethoor");
		} catch (RdbmsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private static void testUseDBNietBestaand() {
		try {
			r.useDatabase("Dezebestaatookniet");
		} catch (RdbmsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private static void testTabel() {
		try {
			r.useDatabase("FietsDb");
			r.createTable("test", new ArrayList<Veld>(), new ArrayList<Groep>(), new ArrayList<ForeignKey>());
		} catch (RdbmsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			r.useDatabase("FietsDb");
			ArrayList<Veld> velden = new ArrayList<Veld>();
			velden.add(new Veld("test", "int", true));
			r.createTable("TRACK", velden, new ArrayList<Groep>(), new ArrayList<ForeignKey>());
		} catch (RdbmsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			ArrayList<Veld> velden = new ArrayList<Veld>();
			velden.add(new Veld("test", "int", true));
			ArrayList<Groep> groepen = new ArrayList<Groep>();
			Groep g = new Groep(r.useDatabase("FietsDb"), true, false);
			g.addGroepAttr(new Veld("test2", "int", false));
			groepen.add(g);
			r.createTable("Test", velden, groepen, new ArrayList<ForeignKey>());
		} catch (RdbmsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			ArrayList<Veld> velden = new ArrayList<Veld>();
			Veld v = new Veld("test", "int", true);
			velden.add(v);
			ArrayList<Groep> groepen = new ArrayList<Groep>();
			Groep prim = new Groep(r.useDatabase("FietsDb"), true, false);
			groepen.add(prim);
			Groep g = new Groep(r.useDatabase("FietsDb"), false, true);
			g.addGroepAttr(v);
			groepen.add(g);
			r.createTable("Test", velden, groepen, new ArrayList<ForeignKey>());
		} catch (RdbmsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			ArrayList<Veld> velden = new ArrayList<Veld>();
			Veld v = new Veld("test", "int", true);
			velden.add(v);
			ArrayList<Groep> groepen = new ArrayList<Groep>();
			Groep g = new Groep(r.useDatabase("FietsDb"), false, false);
			g.addGroepAttr(v);
			r.createTable("Test", velden, groepen, new ArrayList<ForeignKey>());
		} catch (RdbmsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private static void testInsert() {
		try {
			ArrayList<Object> waardes = new ArrayList<Object>();
			waardes.add("1");
			r.useDatabase("FietsDb");
			r.insert("test", new ArrayList<String>(), waardes);
		} catch (RdbmsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			r.useDatabase("FietsDb");
			ArrayList<String> velden = new ArrayList<String>();
			velden.add("Nummer");
			velden.add("Naam");
			velden.add("Rel-date");
			ArrayList<Object> waardes1 = new ArrayList<Object>();
			waardes1.add("Nummer");
			waardes1.add("test");
			waardes1.add("datum");
			r.insert("TRACK", velden, waardes1);
		} catch (RdbmsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			r.useDatabase("FietsDb");
			ArrayList<String> velden = new ArrayList<String>();
			velden.add("Nummer");
			ArrayList<Object> waardes1 = new ArrayList<Object>();
			waardes1.add("5");
			r.insert("TRACK", velden, waardes1);
		} catch (RdbmsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private static void testDelete() {
		try {
			r.useDatabase("FietsDb");
			r.delete("KNPTRACK", new Criteria("Track", "=", "1"));
			System.out.println(r.select("KNPTRACK", null));
		} catch (RdbmsException e) {
			e.printStackTrace();
		}
	}

	private static void testInsertDubbel() {
		testInsertInto();
	}

	private static void createDatabase() {
		DBManager dbm = new DBManager();
		try {

			Connection con = dbm.openConnection();

			System.out.println("Connectie geopend");

			// Drop tabellen als ze bestaan
			dropTables(con);

			System.out.println("Alles gedropt");

			// Maak de tabellen aan
			createTables(con);

			System.out.println("Tabellen aangemaakt");

			// Insert de metadatabase in de database
			insertData(con);

			System.out.println("Data toegevoegd");

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			dbm.closeConnection();
		}
	}

	private static void dropTables(Connection con) throws SQLException {
		con.prepareStatement("DROP TABLE IF EXISTS groep_attr").execute();
		con.prepareStatement("DROP TABLE IF EXISTS foreign_key").execute();
		con.prepareStatement("DROP TABLE IF EXISTS groep").execute();
		con.prepareStatement("DROP TABLE IF EXISTS veld").execute();
		con.prepareStatement("DROP TABLE IF EXISTS tabel").execute();
		con.prepareStatement("DROP TABLE IF EXISTS database_impl").execute();
		con.prepareStatement("DROP TABLE IF EXISTS KNPTRACK").execute();
		con.prepareStatement("DROP TABLE IF EXISTS KNOOPPUNT").execute();
		con.prepareStatement("DROP TABLE IF EXISTS TRACK").execute();
	}

	private static void createTables(Connection con) throws SQLException {
		con.prepareStatement(
				"CREATE TABLE database_impl(naam VARCHAR(255) NOT NULL, CONSTRAINT pk_database_impl PRIMARY KEY(naam))")
				.execute();
		con.prepareStatement(
				"CREATE TABLE tabel(naam VARCHAR(255) NOT NULL, database_naam VARCHAR(255) NOT NULL, CONSTRAINT pk_tabel PRIMARY KEY (naam, database_naam), FOREIGN KEY (database_naam) REFERENCES database_impl(naam) )")
				.execute();
		con.prepareStatement(
				"CREATE TABLE veld(naam VARCHAR(255) NOT NULL, tabel_naam VARCHAR(255) NOT NULL, database_naam VARCHAR(255) NOT NULL, type VARCHAR(255), isNotNull BOOLEAN DEFAULT 0, CONSTRAINT pk_veld PRIMARY KEY(naam, tabel_naam, database_naam), FOREIGN KEY(tabel_naam, database_naam) REFERENCES tabel(naam, database_naam))")
				.execute();
		con.prepareStatement(
				"CREATE TABLE groep(id INT GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), tabel_naam VARCHAR(255) NOT NULL, database_naam VARCHAR(255) NOT NULL, isPrimary BOOLEAN DEFAULT 0, isAlternative BOOLEAN DEFAULT 0, CONSTRAINT pk_groep PRIMARY KEY(id), FOREIGN KEY(tabel_naam, database_naam) REFERENCES tabel(naam, database_naam))")
				.execute();
		con.prepareStatement(
				"CREATE TABLE groep_attr(groep_id INT NOT NULL, veld_naam VARCHAR(255) NOT NULL, tabel_naam VARCHAR(255) NOT NULL, database_naam VARCHAR(255) NOT NULL, CONSTRAINT pk_groep_attr PRIMARY KEY(groep_id, veld_naam, tabel_naam, database_naam), FOREIGN KEY(groep_id) REFERENCES groep(id), FOREIGN KEY(veld_naam, tabel_naam, database_naam) REFERENCES veld(naam, tabel_naam, database_naam))")
				.execute();
		con.prepareStatement(
				"CREATE TABLE foreign_key(from_groep INT NOT NULL, to_groep INT NOT NULL, CONSTRAINT pk_fk PRIMARY KEY(from_groep, to_groep), FOREIGN KEY(from_groep) REFERENCES groep(id), FOREIGN KEY(to_groep) REFERENCES groep(id))")
				.execute();
	}

	private static void insertData(Connection con) throws SQLException {
		// INSERT database (naam)
		con.prepareStatement("INSERT INTO database_impl VALUES('myrdbms')")
				.execute();

		// INSERT tabellen (naam, database)
		con.prepareStatement(
				"INSERT INTO tabel VALUES('database_impl', 'myrdbms')")
				.execute();
		con.prepareStatement("INSERT INTO tabel VALUES('tabel', 'myrdbms')")
				.execute();
		con.prepareStatement("INSERT INTO tabel VALUES('veld', 'myrdbms')")
				.execute();
		con.prepareStatement("INSERT INTO tabel VALUES('groep', 'myrdbms')")
				.execute();
		con.prepareStatement(
				"INSERT INTO tabel VALUES('groep_attr', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO tabel VALUES('foreign_key', 'myrdbms')").execute();

		// INSERT velden (naam, tabel, database, type, isPrimary, isNotNull,
		// isUnique)
		// database
		con.prepareStatement(
				"INSERT INTO veld VALUES('naam', 'database_impl', 'myrdbms', 'varchar(255)', true)")
				.execute();

		// tabel
		con.prepareStatement(
				"INSERT INTO veld VALUES('naam', 'tabel', 'myrdbms', 'varchar(255)', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES('database_naam', 'tabel', 'myrdbms', 'varchar(255)', true)")
				.execute();

		// veld
		con.prepareStatement(
				"INSERT INTO veld VALUES('naam', 'veld', 'myrdbms', 'varchar(255)', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES('database_naam', 'veld', 'myrdbms', 'varchar(255)', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES('tabel_naam', 'veld', 'myrdbms', 'varchar(255)', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES('type', 'veld', 'myrdbms', 'varchar(255)', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES('isNotNull', 'veld', 'myrdbms', 'BOOLEAN', true)")
				.execute();

		// groep
		con.prepareStatement(
				"INSERT INTO veld VALUES ('id', 'groep', 'myrdbms', 'int', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES ('tabel_naam', 'groep', 'myrdbms', 'varchar(255)', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES ('database_naam', 'groep', 'myrdbms', 'varchar(255)', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES ('isPrimary', 'groep', 'myrdbms', 'BOOLEAN', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES ('isAlternative', 'groep', 'myrdbms', 'BOOLEAN', true)")
				.execute();

		// groep_attr
		con.prepareStatement(
				"INSERT INTO veld VALUES ('groep_id', 'groep_attr', 'myrdbms', 'int', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES ('veld_naam', 'groep_attr', 'myrdbms', 'varchar(255)', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES ('tabel_naam', 'groep_attr', 'myrdbms', 'varchar(255)', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES ('database_naam', 'groep_attr', 'myrdbms', 'varchar(255)', true)")
				.execute();

		// foreign_key
		con.prepareStatement(
				"INSERT INTO veld VALUES ('from_groep', 'foreign_key', 'myrdbms', 'int', true)")
				.execute();
		con.prepareStatement(
				"INSERT INTO veld VALUES ('to_groep', 'foreign_key', 'myrdbms', 'int', true)")
				.execute();

		// INSERT groep (id, tabel, database, isPrimary, isAlternative
		// database
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('database_impl', 'myrdbms', true, false)")
				.execute();
		// tabel
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('tabel', 'myrdbms', true, false)")
				.execute();
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('tabel', 'myrdbms', false, false)")
				.execute();

		// veld
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('veld', 'myrdbms', true, false)")
				.execute();
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('veld', 'myrdbms', false, false)")
				.execute();

		// groep
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('groep', 'myrdbms', true, false)")
				.execute();
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('groep', 'myrdbms', false, false)")
				.execute();

		// groep_attr
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('groep_attr', 'myrdbms', true, false)")
				.execute();
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('groep_attr', 'myrdbms', false, false)")
				.execute();
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('groep_attr', 'myrdbms', false, false)")
				.execute();

		// foreign_key
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('foreign_key', 'myrdbms', true, false)")
				.execute();
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('foreign_key', 'myrdbms', false, false)")
				.execute();
		con.prepareStatement(
				"INSERT INTO groep (tabel_naam, database_naam, isPrimary, isAlternative) VALUES ('foreign_key', 'myrdbms', false, false)")
				.execute();

		ResultSet rs = con.prepareStatement("SELECT MAX(id) FROM groep")
				.executeQuery();
		int lastId = 0;
		while (rs.next()) {
			lastId = rs.getInt(1);
		}
		// INSERT groep_attr (groep_id, veld_naam, tabel_naam, database_naam)
		// database
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 12)
						+ ", 'naam', 'database_impl', 'myrdbms')").execute();

		// tabel
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 11)
						+ ", 'naam', 'tabel', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 11)
						+ ", 'database_naam', 'tabel', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 10)
						+ ", 'database_naam', 'tabel', 'myrdbms')").execute();

		// veld
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 9)
						+ ", 'naam', 'veld', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 9)
						+ ", 'tabel_naam', 'veld', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 9)
						+ ", 'database_naam', 'veld', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 8)
						+ ", 'tabel_naam', 'veld', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 8)
						+ ", 'database_naam', 'veld', 'myrdbms')").execute();

		// groep
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 7)
						+ ", 'id', 'groep', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 6)
						+ ", 'tabel_naam', 'groep', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 6)
						+ ", 'database_naam', 'groep', 'myrdbms')").execute();

		// groep_attr
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 5)
						+ ", 'groep_id', 'groep_attr', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 5)
						+ ", 'veld_naam', 'groep_attr', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 5)
						+ ", 'tabel_naam', 'groep_attr', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 5)
						+ ", 'database_naam', 'groep_attr', 'myrdbms')")
				.execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 4)
						+ ", 'groep_id', 'groep_attr', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 3)
						+ ", 'veld_naam', 'groep_attr', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 3)
						+ ", 'tabel_naam', 'groep_attr', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 3)
						+ ", 'database_naam', 'groep_attr', 'myrdbms')")
				.execute();

		// foreign_key
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 2)
						+ ", 'from_groep', 'foreign_key', 'myrdbms')")
				.execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 2)
						+ ", 'to_groep', 'foreign_key', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId - 1)
						+ ", 'to_groep', 'foreign_key', 'myrdbms')").execute();
		con.prepareStatement(
				"INSERT INTO groep_attr VALUES (" + (lastId)
						+ ", 'from_groep', 'foreign_key', 'myrdbms')")
				.execute();

		// INSERT foreign_key (from_groep, to_groep)
		// tabel to database
		con.prepareStatement(
				"INSERT INTO foreign_key VALUES (" + (lastId - 10) + ", "
						+ (lastId - 12) + ")").execute();
		// veld to tabel
		con.prepareStatement(
				"INSERT INTO foreign_key VALUES (" + (lastId - 8) + ", "
						+ (lastId - 11) + ")").execute();
		// groep to tabel
		con.prepareStatement(
				"INSERT INTO foreign_key VALUES (" + (lastId - 6) + ", "
						+ (lastId - 11) + ")").execute();
		// groepattr to groep
		con.prepareStatement(
				"INSERT INTO foreign_key VALUES (" + (lastId - 4) + ", "
						+ (lastId - 7) + ")").execute();
		// groepattr to veld
		con.prepareStatement(
				"INSERT INTO foreign_key VALUES (" + (lastId - 3) + ", "
						+ (lastId - 9) + ")").execute();
		// foreignkey to groep
		con.prepareStatement(
				"INSERT INTO foreign_key VALUES (" + (lastId - 1) + ", "
						+ (lastId - 7) + ")").execute();
		con.prepareStatement(
				"INSERT INTO foreign_key VALUES (" + (lastId) + ", "
						+ (lastId - 7) + ")").execute();
	}
}
